package com.hzf.wxplatform.web.utils;

import com.github.wenhao.geohash.GeoSearch;
import com.github.wenhao.geohash.domain.GeoRange;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GeoHashHelper {

        public static final double Max_Lat = 90;
        public static  final double Min_Lat = -90;
        public static final double Max_Lng = 180;
        public static final double Min_Lng = -180;
        private static final int length = 20;
        private static final double latUnit = (Max_Lat - Min_Lat) / (1 << 20);
        private static final double lngUnit = (Max_Lng - Min_Lng) / (1 << 20);
        private static final String[] base32Lookup =
                {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "b", "c", "d", "e", "f", "g", "h",
                        "j", "k", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};

        private static void convert(double min, double max, double value, List<Character> list) {
            if (list.size() > (length - 1)) {
                return;
            }
            double mid = (max + min) / 2;
            if (value < mid) {
                list.add('0');
                convert(min, mid, value, list);
            } else {
                list.add('1');
                convert(mid, max, value, list);
            }
        }

        private static String base32Encode(final String str) {
            String unit = "";
            StringBuilder sb = new StringBuilder();
            for (int start = 0; start < str.length(); start = start + 5) {
                unit = str.substring(start, start + 5);
                sb.append(base32Lookup[convertToIndex(unit)]);
            }
            return sb.toString();
        }

        private static int convertToIndex(String str) {
            int length = str.length();
            int result = 0;
            for (int index = 0; index < length; index++) {
                result += str.charAt(index) == '0' ? 0 : 1 << (length - 1 - index);
            }
            return result;
        }

        public static String encode(double lat, double lng) {
            List<Character> latList = new ArrayList<Character>();
            List<Character> lngList = new ArrayList<Character>();
            convert(Min_Lat, Max_Lat, lat, latList);
            convert(Min_Lng, Max_Lng, lng, lngList);
            StringBuilder sb = new StringBuilder();
            for (int index = 0; index < latList.size(); index++) {
                sb.append(lngList.get(index)).append(latList.get(index));
            }
            return base32Encode(sb.toString());
        }

        public static List<String> around(double lat, double lng) {
            List<String> list = new ArrayList<String>();
            list.add(encode(lat, lng));
            list.add(encode(lat + latUnit, lng));
            list.add(encode(lat - latUnit, lng));
            list.add(encode(lat, lng + lngUnit));
            list.add(encode(lat, lng - lngUnit));
            list.add(encode(lat + latUnit, lng + lngUnit));
            list.add(encode(lat + latUnit, lng - lngUnit));
            list.add(encode(lat - latUnit, lng + lngUnit));
            list.add(encode(lat - latUnit, lng - lngUnit));
            return list;
        }
        public static Map<String,Long> getMax(double lat,double lng,int dict){
            Map<String,Long> map = new HashMap<>();
            long min0 = 0;//最小点
            long max0 = 0;//最大点
            long min1 = 0;//最小点
            long max1 = 0;//最大点
            long min2 = 0;//最小点
            long max2 = 0;//最大点
            long min3 = 0;//最小点
            long max3 = 0;//最大点
            long min4 = 0;//最小点
            long max4 = 0;//最大点
            long min5 = 0;//最小点
            long max5 = 0;//最大点
            long min6 = 0;//最小点
            long max6 = 0;//最大点
            long min7 = 0;//最小点
            long max7 = 0;//最大点        double min6;//最小点
            long min8 = 0;//最大点        double min6;//最小点
            long max8 = 0;//最大点
            List<GeoRange> geoRanges = GeoSearch.range(lat, lng, dict);
            for (int i = 0; i < geoRanges.size(); i++) {
                switch (i) {
                    case 0:
                        min0 = geoRanges.get(i).getMin();
                        max0 = geoRanges.get(i).getMax();
                    case 1:
                        min1 = geoRanges.get(i).getMin();
                        max1 = geoRanges.get(i).getMax();
                    case 2:
                        min2 = geoRanges.get(i).getMin();
                        max2 = geoRanges.get(i).getMax();
                    case 3:
                        min3 = geoRanges.get(i).getMin();
                        max3 = geoRanges.get(i).getMax();
                    case 4:
                        min4 = geoRanges.get(i).getMin();
                        max4 = geoRanges.get(i).getMax();
                    case 5:
                        min5 = geoRanges.get(i).getMin();
                        max5 = geoRanges.get(i).getMax();
                    case 6:
                        min6 = geoRanges.get(i).getMin();
                        max6 = geoRanges.get(i).getMax();
                    case 7:
                        min7 = geoRanges.get(i).getMin();
                        max7 = geoRanges.get(i).getMax();
                    case 8:
                        min8 = geoRanges.get(i).getMin();
                        max8 = geoRanges.get(i).getMax();
                }
            }
            map.put("min0",min0);
            map.put("max0",max0);
            map.put("min1",min1);
            map.put("max1",max1);
            map.put("min2",min2);
            map.put("max2",max2);
            map.put("min3",min3);
            map.put("max3",max3);
            map.put("min4",min4);
            map.put("max4",max4);
            map.put("min5",min5);
            map.put("max5",max5);
            map.put("min6",min6);
            map.put("max6",max6);
            map.put("min7",min7);
            map.put("max7",max7);
            map.put("min8",min8);
            map.put("max8",max8);
            return map;
        }
}
